﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;

namespace DarwinIsDead.Traits {
    public class DirectMovement : Trait {
        Player player;
        private int healthBonus;
        private float runSpeed;
        private float direction;
        private float bounce;

        private Texture2D sprite;
        private SpriteFont debugFont;
        
        // Ctor
        public DirectMovement(Zombie owner, World world=null)
            : base(owner, world) {
        }

        public override object Clone() {
            DirectMovement ret = new DirectMovement(Owner, World);
            return ret;
        }
        
        public override void Initialize() {
            // Put anything that couldn't be put into the constructor here.
            // That is, anything that depends on other Traits and couldn't be
            // initialized until the Zombie was fully formed.

            // Apply any changes to the owning Zombie that doesn't involve
            // accessing other Traits
            Owner.HitBox.Width += 64;   // Add some dimension to the zombie's hitbox
            Owner.HitBox.Height += 64;

            // Load sound, graphics, etc.
            sprite = World.Game.Content.Load<Texture2D>("Sprites\\Traits\\sprLegs");
            debugFont = World.Game.Content.Load<SpriteFont>("Fonts\\Courier New");

            runSpeed = 50f; // Moves 50 pixels per second
            healthBonus = 40;  // Adds 40 health to this zombie
            bounce = 0;

            List<Entity> players = World.GetEntities<Player>();
            if (players.Count > 0) {
                player = (Player)players[0];
            }

            Level = 1;
        }

        protected override void AdjustLevel(int level) {
            // Apply any changes that occur with leveling up.
            runSpeed = level * 50f;
            
            int oldMaxHealth = Owner.MaxHealth;
            Owner.MaxHealth += level * healthBonus;
            // Scale the remaining health to the new cap
            Owner.Health = (int)(((float)Owner.Health / oldMaxHealth) *
                Owner.MaxHealth);
        }

        protected override void InternalUpdate(GameTime gameTime) {
            // Our delta time (time between game updates) in seconds.
            // You can use whatever format you want, but this is my preferred.
            float dt = gameTime.ElapsedGameTime.Milliseconds / 1000f;

            // Move to player and hug the bastard
            if (player != null) {
                // Get the distance between the zombie and the player
                float dpx = player.Position.X - Owner.Position.X;
                float dpy = player.Position.Y - Owner.Position.Y;

                double dist = Math.Abs(dpx + dpy);
                if (dist > 100f) {
                    // Get the angle between the zombie and the player
                    direction = (float)Math.Atan2(dpy, dpx);

                    // Get our movement components
                    float dx = runSpeed * dt * (float)Math.Cos(direction);
                    float dy = runSpeed * dt * (float)Math.Sin(direction);

                    // Move the zombie
                    Owner.Move(dx, dy);
                }
                // A little bounce in his step
                bounce = 4f * Math.Abs(
                    (float)Math.Sin(2f * Math.PI *
                        gameTime.TotalGameTime.Milliseconds / 1000.0)
                );
            }
        }

        protected override void InternalDraw(SpriteBatch spriteBatch, Color color) {
            Vector2 drawPosition = new Vector2(Owner.Position.X, Owner.Position.Y);
            drawPosition.Y += 16f + bounce;  // Draw the legs a little lower on the body
                                             // And with some bounce in his stride

            // Draw the damn thing
            spriteBatch.Draw(sprite, drawPosition, color);
        }
    }
}
